package mju.cxf.service.impl;

import mju.cxf.dto.EmailDTO;
import mju.cxf.entity.Email;
import lombok.extern.slf4j.Slf4j;
import mju.cxf.constant.MessageConstant;
import mju.cxf.exception.BaseException;
import mju.cxf.exception.LoginFailedException;
import mju.cxf.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeUnit;

/**
 * 邮箱相关业务
 */
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {
    private RedisTemplate<String,Object > redisTemplate;
    private JavaMailSenderImpl mailSender;
    @Autowired
    public EmailServiceImpl(RedisTemplate<String, Object> redisTemplate, JavaMailSenderImpl mailSender) {
        this.redisTemplate = redisTemplate;
        this.mailSender = mailSender;
    }
    /**
     * U发送邮箱验证码验证码
     * @param emailDTO
     */
    @Override
    public void getEmailCode(EmailDTO emailDTO) {
//        log.info("获取验证码{}",emailDTO);
        Email em = new Email("卡先锋验证", emailDTO.getTo(), true);
        String key = em.getTo();
        //获取分布式锁 同线程其他访问为false
        boolean locked = redisTemplate.opsForValue().setIfAbsent(key + "_lock", "locked", 5, TimeUnit.MINUTES);
        if (!locked) {
            throw new BaseException(MessageConstant.MESSAGE_TOO_MANY_REQUESTS);
        }

        try {
            String existingCode = (String) redisTemplate.opsForValue().get(key);
            if (existingCode != null) {
                long expireTime = redisTemplate.getExpire(key, TimeUnit.MINUTES);
                if (expireTime >= 4) {
                    throw new LoginFailedException(MessageConstant.MESSAGE_VERIFICATION_CODE_LIMIT);
                }
            }
            // 邮件发送或编码相关代码
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            // 邮件主题
            helper.setSubject(em.getSubject());
            // 邮件正文，第二个参数设置为 true 表示内容为 HTML
            helper.setText(em.getText(), true);
            // 发送对象
            helper.setTo(em.getTo());
            // 发送人
            helper.setFrom(new InternetAddress(Email.from, "卡先锋"));
            // 发送邮件
            mailSender.send(mimeMessage);
            redisTemplate.opsForValue().set(key, em.getCode(), 5, TimeUnit.MINUTES);
        } catch (MessagingException e) {
            throw new BaseException("邮箱业务异常");
            // 处理邮件异常
        } catch (UnsupportedEncodingException e) {
            throw new BaseException("邮箱编码异常");
            // 处理编码异常
        }catch (MailSendException e) {
            throw new LoginFailedException("错误的邮箱格式");
            // 进一步处理，例如重试或记录日志
        }
        finally {
            // 确保释放锁
            redisTemplate.delete(key + "_lock");
        }
    }
    @Override
    public void getKey(EmailDTO emailDTO) {
//        log.info("获取验证码{}",emailDTO);
        Email em = new Email("卡先锋获取key验证", emailDTO.getTo(), true);
        String key = em.getTo();
        //获取分布式锁 同线程其他访问为false
        boolean locked = redisTemplate.opsForValue().setIfAbsent(key + "_lock", "locked", 5, TimeUnit.MINUTES);
        if (!locked) {
            throw new BaseException(MessageConstant.MESSAGE_TOO_MANY_REQUESTS);
        }

        try {
            String existingCode = (String) redisTemplate.opsForValue().get("key:"+key);
            if (existingCode != null) {
                long expireTime = redisTemplate.getExpire("key:"+key, TimeUnit.MINUTES);
                if (expireTime >= 4) {
                    throw new LoginFailedException(MessageConstant.MESSAGE_VERIFICATION_CODE_LIMIT);
                }
            }
            // 邮件发送或编码相关代码
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            // 邮件主题
            helper.setSubject(em.getSubject());
            // 邮件正文，第二个参数设置为 true 表示内容为 HTML
            helper.setText(em.getText(), true);
            // 发送对象
            helper.setTo(em.getTo());
            // 发送人
            helper.setFrom(new InternetAddress(Email.from, "卡先锋"));
            // 发送邮件
            mailSender.send(mimeMessage);
            redisTemplate.opsForValue().set("key:"+key, em.getCode(), 5, TimeUnit.MINUTES);
        } catch (MessagingException e) {
            throw new BaseException("邮箱业务异常");
            // 处理邮件异常
        } catch (UnsupportedEncodingException e) {
            throw new BaseException("邮箱编码异常");
            // 处理编码异常
        }catch (MailSendException e) {
            throw new LoginFailedException("错误的邮箱格式");
            // 进一步处理，例如重试或记录日志
        }
        finally {
            // 确保释放锁
            redisTemplate.delete(key + "_lock");
        }
    }
}
